package com.tangyuan.video.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tangyuan.common.result.Result;
import com.tangyuan.common.result.ResultCodeEnum;
import com.tangyuan.common.util.*;
import com.tangyuan.dto.VideoCommentDto;
import com.tangyuan.dto.VideoPublisherDto;
import com.tangyuan.model.*;
import com.tangyuan.video.mapper.VideoCommentMapper;
import com.tangyuan.video.mapper.VideoCommentTrumpMapper;
import com.tangyuan.video.mapper.VideoMapper;
import com.tangyuan.video.service.VideoCommentService;
import com.tangyuan.video.service.VideoService;
import com.tangyuan.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
@Slf4j
public class VideoCommentServiceImpl extends ServiceImpl<VideoCommentMapper, VideoComment> implements VideoCommentService {

    @Autowired
    VideoCommentMapper videoCommentMapper;
    @Autowired
    VideoService videoService;
    @Autowired
    VideoCommentTrumpMapper videoCommentTrumpMapper;

    @Override
    public Result saveVideoComment(VideoCommentDto videoCommentDto, String token) {
        User user = CommStatus.getUser(token);
        Video video = videoService.getById(videoCommentDto.getVideoId());
        if(video==null){
            return Result.build(null, ResultCodeEnum.NO_DATA);
        }
        VideoComment videoComment = createVideoComment(videoCommentDto, user);
        VideoCommentVo videoCommentVo = BeanUtil.copyProperties(videoComment, VideoCommentVo.class);

        if (videoCommentDto.getParentId()!=null&&videoCommentDto.getParentId()!=0){
            VideoComment videoCommentParent = videoCommentMapper.selectById(videoCommentDto.getParentId());
            videoCommentVo.setParentName(videoCommentParent.getUserName());
            if (videoCommentParent.getReplyId() != null && videoCommentParent.getReplyId() != 0){
                videoComment.setReplyId(videoCommentParent.getReplyId());
                videoCommentVo.setReplyId(videoCommentParent.getReplyId());
            }else {
                videoComment.setReplyId(videoCommentParent.getId());
                videoCommentVo.setReplyId(videoCommentParent.getId());
            }
        }else {
            videoComment.setReplyId(0L);
            videoComment.setParentId(0L);
            videoCommentVo.setParentName(user.getName());
            videoCommentVo.setReplyId(0L);
            videoCommentVo.setParentId(0L);
            videoCommentVo.setCommentVos(new ArrayList<>());
        }
        videoCommentMapper.saveVideoComment(videoComment);
        videoCommentVo.setId(videoComment.getId());

        //添加评论数

        video.setCommentNum(video.getCommentNum()+1);
        videoService.updateById(video);
        return Result.ok(videoCommentVo);
    }

    @Override
    public Result saveReplyComment(VideoCommentDto videoCommentDto, String token) {
        User user = CommStatus.getUser(token);
        VideoComment videoComment = createVideoComment(videoCommentDto, user);
        //添加创建时间
        videoComment.setCreateTime(new Date());
        if (videoComment.getParentId() != null && videoComment.getParentId() != 0) {
            VideoComment comment = this.getById(videoComment.getParentId());
            if (comment != null) {
                if (comment.getReplyId() != null && comment.getReplyId() != 0) {
                    if (Long.toString(comment.getReplyId()).length() != 19) {
                        videoComment.setReplyId(comment.getReplyId());
                    } else {
                        videoComment.setReplyId(comment.getId());
                    }
                } else {
                    videoComment.setReplyId(comment.getId());
                }
            }
        } else {
            videoComment.setReplyId(0L);
            videoComment.setParentId(0L);
        }
        videoCommentMapper.insert(videoComment);
        return Result.ok();
    }

    private VideoComment createVideoComment(VideoCommentDto videoCommentDto, User user){
        VideoComment videoComment = BeanUtil.copyProperties(videoCommentDto, VideoComment.class);
        videoComment.setCreateTime(DateUtil.changeLocalDateTimeToDate(LocalDateTime.now()));
        long round = Math.round(Double.valueOf( DateUtil.changeLocalDateTimeToDate(LocalDateTime.now()).getTime())/1000);
        videoComment.setCreateBy(String.valueOf(round));
        videoComment.setUserIcon(user.getHeadImage());
        videoComment.setUserId(user.getId());
        videoComment.setUserName(user.getName());
        //添加创建时间
        videoComment.setCreateTime(new Date());

        videoComment.setArea(user.getProvince());
        return videoComment;
    }

    @Override
    public Result selectCommentByVideoId(Long videoId, Integer pageSize, Integer pageNum, Long userId) {
        PageHelper.startPage(pageNum, pageSize);
        //查询10条一级评论
        List<VideoCommentVo> videoCommentVos = videoCommentMapper.selectCommentByVideoId(videoId);
        VideoCommentCountVo videoCommentCountVo = new VideoCommentCountVo();
        videoCommentCountVo.setCommentCount(videoCommentMapper.findAllCommentCount(videoId));
        //非空判断为空直接返回
        if(CollUtils.isEmpty(videoCommentVos)){
            return Result.ok(videoCommentCountVo);
        }
        //获取1级评论的id
        List<Long> oneCommentIds = videoCommentVos.stream().map(VideoCommentVo::getId).collect(Collectors.toList());
        //根据1级评论的id查询2级评论
        List<VideoCommentVo> twoComment = videoCommentMapper.findTwoComment(videoId,oneCommentIds);
        //获取2级评论id
        List<Long> twoCommentIds = twoComment.stream().map(VideoCommentVo::getId).collect(Collectors.toList());
        //1级2级id合一起
        oneCommentIds.addAll(twoCommentIds);
        //查询所有评论的点赞
        List<VideoCommentTrump> videoCommentTrumpList= videoCommentTrumpMapper.selectByCommentIds(oneCommentIds);
        //封装一级评论喜欢不喜欢数
        for (VideoCommentVo videoCommentVo : videoCommentVos) {
            if (!CollectionUtil.isEmpty(videoCommentTrumpList)){
                for (VideoCommentTrump videoCommentTrump : videoCommentTrumpList) {
                    if (videoCommentTrump.getCommentId().equals(videoCommentVo.getId())){
                        if (videoCommentTrump.getType()==0){
                            videoCommentVo.setIslike(1);
                            videoCommentVo.setLikeCount(videoCommentVo.getLikeCount()+1);
                        }else if (videoCommentTrump.getType()==1){
                            videoCommentVo.setIsdislike(1);
                            videoCommentVo.setDisLikeCount(videoCommentVo.getDisLikeCount()+1);
                        }
            }
                    }
            }
        }
        //封装二级评论喜欢不喜欢数
        for (VideoCommentVo videoCommentVo : twoComment) {
            if (!CollectionUtil.isEmpty(videoCommentTrumpList)){
                for (VideoCommentTrump videoCommentTrump : videoCommentTrumpList) {
                    if (videoCommentTrump.getCommentId().equals(videoCommentVo.getId())){
                        if (videoCommentTrump.getType()==0){
                            videoCommentVo.setIslike(1);
                            videoCommentVo.setLikeCount(videoCommentVo.getLikeCount()+1);
                        }else if (videoCommentTrump.getType()==1){
                            videoCommentVo.setIsdislike(1);
                            videoCommentVo.setDisLikeCount(videoCommentVo.getDisLikeCount()+1);
                        }
                    }
                }
            }
        }
        //将2级评论封装进1级评论
        for (VideoCommentVo rootCollect : videoCommentVos) {
            List<VideoCommentVo> twoCommon = twoComment.stream().filter(comment -> rootCollect.getId().equals(comment.getReplyId())).collect(Collectors.toList());
            if(!CollUtils.isEmpty(twoCommon)){
                Map<Long, String> map = twoCommon.stream().collect(Collectors.toMap(VideoCommentVo::getId,VideoCommentVo::getUserName,(h1,h2)->h1));
                for (VideoCommentVo comment : twoCommon) {
                    //如果ParentId和ReplyId不一致,则证明该条评论是在回复二级评论,设置parentName(被回复人用户名)
                    if(!comment.getParentId().equals(comment.getReplyId())){
                        comment.setParentName(map.get(comment.getParentId()));
                    }
                }
            }
            rootCollect.setCommentVos(twoCommon);
        }
        videoCommentCountVo.setCommentVos(videoCommentVos);

        return Result.ok(videoCommentCountVo);
    }

    @Override
    public Result selectReplayCommentByCommentId(Long videoId, Integer pageSize, Integer pageNum) {
        PageHelper.startPage(pageNum, pageSize);
        List<VideoReplayCommentVo> list = videoCommentMapper.selectReplayCommentByCommentId(videoId);
        PageInfo<VideoReplayCommentVo> videoReplayCommentVoPageInfo = new PageInfo<>(list);
        for (VideoReplayCommentVo videoReplayCommentVo : videoReplayCommentVoPageInfo.getList()) {
            LambdaQueryWrapper<VideoComment> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(VideoComment::getReplyId, videoReplayCommentVo.getReplyId());
            List<VideoComment> list1 = this.list(queryWrapper);
            videoReplayCommentVo.setCommentVos(list1);
        }
        return Result.ok(videoReplayCommentVoPageInfo);
    }

    @Override
    public Result addCommentThumpById(Long id, Long userId) {
        VideoCommentTrump videoCommentTrump= videoCommentTrumpMapper.selectByCommentIdAndUserId(userId,id);
        if (videoCommentTrump !=null){
            return Result.ok();
        }
        videoCommentMapper.addCommentThumpById(id);
        videoCommentMapper.saveTrumpInfo(userId, id);
        return Result.ok();
    }

    @Override
    public Result removeCommentThumpById(Long id, Long userId) {
        videoCommentMapper.removeCommentThumpById(id);
        videoCommentMapper.removeTrumpInfo(userId, id);
        return Result.ok();
    }

    @Override
    public Result disLike(Long id, Long userId) {
        VideoCommentTrump videoCommentTrump =videoCommentTrumpMapper.selectByDisCommentId(id,userId);
        if (videoCommentTrump !=null){
            return Result.ok();
        }
        videoCommentMapper.disLike(userId, id);
        return Result.ok();
    }

    @Override
    public Result removeDisLike(Long id, Long userId) {
        videoCommentMapper.removeDisLike(userId, id);
        return Result.ok();
    }

    @Override
    public void updateVideoCommentMessage(VideoPublisherDto dto){
        if(dto == null ||
                (dto.getUserId() == null || dto.getUserId() == 0) ||
                (org.apache.commons.lang3.StringUtils.isEmpty(dto.getNickName()) && StringUtils.isEmpty(dto.getUrl()))){
            log.error("视频评论修改参数不可为空");
            return;
        }
        baseMapper.update(null,new LambdaUpdateWrapper<VideoComment>()
                .eq(VideoComment::getUserId,dto.getUserId())
                .set(!StringUtils.isEmpty(dto.getUrl()),VideoComment::getUserIcon,dto.getUrl())
                .set(!StringUtils.isEmpty(dto.getNickName()),VideoComment::getUserName,dto.getNickName())
        );
    }
}
